package br.ufrn.sipac.patrimonio.coletor.integrationTest;

import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import android.test.ActivityInstrumentationTestCase2;
import br.ufrn.sipac.patrimonio.auxiliares.ConstantesOperacoes;
import br.ufrn.sipac.patrimonio.auxiliares.StatusLevantamento;
import br.ufrn.sipac.patrimonio.coletor.activity.AutenticacaoActivity;
import br.ufrn.sipac.patrimonio.coletor.activity.LeituraActivity;
import br.ufrn.sipac.patrimonio.coletor.controller.DatabaseController;
import br.ufrn.sipac.patrimonio.coletor.controller.MainController;
import br.ufrn.sipac.patrimonio.coletor.dominio.Bem;
import br.ufrn.sipac.patrimonio.coletor.dominio.FinalidadeLevantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.ItemLevantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.Levantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.Localidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.Persistencia;
import br.ufrn.sipac.patrimonio.coletor.dominio.Unidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.UsuarioColetor;
import br.ufrn.sipac.patrimonio.coletor.exception.DatabaseException;
import br.ufrn.sipac.patrimonio.coletor.exception.NegocioException;
import br.ufrn.sipac.patrimonio.coletor.exception.TransmissaoException;
import br.ufrn.sipac.patrimonio.coletor.helper.DatabaseHelper;
import br.ufrn.sipac.patrimonio.coletor.transmissao.GenericSOAP;

public class CadastroLevantamentoIntegrationTest extends
		ActivityInstrumentationTestCase2<LeituraActivity> {
	private LeituraActivity context;

	public CadastroLevantamentoIntegrationTest() {
		super(LeituraActivity.class);
	}

	public CadastroLevantamentoIntegrationTest(String name) {
		super(LeituraActivity.class);
		setName(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
		context = getActivity();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	public final void testPreCondition() {
		assertNotNull(context);
	}

	public final void testFinalizaLevantamento() throws TransmissaoException,
			DatabaseException, SQLException {
		// 1 - Autentica o user.
		fazerLogin();
		// 2 - Inicia novo levantamento
		iniciaNovoLevantamento();
		// 3 - Seleciona unidade e localidade do levantamento.
		selecionaUnidadeLocal();
		// 4 - Adiciona bens
		incluiBens();
		// 5 - Salva levantamento
		gravarLevantamento();
		// 6 - Consultar levantamento
		consultaLevantamento();
	}

	public final void fazerLogin() throws TransmissaoException,
			DatabaseException {
		MainController.setTipoOperacao(ConstantesOperacoes.MODO_ONLINE);
		MainController.setTipoAutenticacao(ConstantesOperacoes.MODO_OFFLINE);
		MainController.setLogin("admin");
		MainController.setSenha("123456");
		MainController.logar(context);
		UsuarioColetor usu = MainController.capturarUsuario(
				MainController.getLogin(), context);
		MainController.setUsuario(usu);
		MainController.findUnidadesPermissao(context);
	}

	public final void iniciaNovoLevantamento() throws DatabaseException,
			TransmissaoException {
		List<FinalidadeLevantamento> finalidades = (List<FinalidadeLevantamento>) MainController
				.findFinalidadesLevantamento(context);
		MainController.setFinalidade(finalidades.get(0));
		MainController.setDescricaoLevantamento("Teste de Integração.");
	}

	public final void selecionaUnidadeLocal() throws NegocioException,
			DatabaseException, TransmissaoException {
		MainController.setUnidade(new Unidade(605));
		List<Localidade> locais = (List<Localidade>) MainController
				.findLocaisByUnidade(context, 605, 1100);
		MainController.setLocalidade(locais.get(0));
		MainController.getLevantamento().setStatus(StatusLevantamento.PENDENTE);
		MainController.getLevantamento().setDataCadastro(new Date());
		DatabaseController.create(MainController.getLevantamento(), context);
	}

	public final void incluiBens() throws NumberFormatException,
			TransmissaoException, DatabaseException {
		GenericSOAP soap = new GenericSOAP();
		Bem bem = soap.findByNumCod(Integer.parseInt("2013000001"), context);
		ItemLevantamento item = new ItemLevantamento();
		item.setBem(bem);
		item.setMarca("Nao informada");
		item.setLevantamento(MainController.getLevantamento());
		item.setEstado(bem.getStatus());
		item.setNumTombamento(String.valueOf(bem.getNumTombamento()));
		item.setDenominacao(bem.getDenominacao());
		MainController.getBensInventariados().add(item);
		DatabaseController.create(item, context);

		bem = soap.findByNumCod(Integer.parseInt("2013000002"), context);
		item = new ItemLevantamento();
		item.setBem(bem);
		item.setMarca("Nao informada");
		item.setLevantamento(MainController.getLevantamento());
		item.setEstado(bem.getStatus());
		item.setNumTombamento(String.valueOf(bem.getNumTombamento()));
		item.setDenominacao(bem.getDenominacao());
		MainController.getBensInventariados().add(item);
		DatabaseController.create(item, context);
	}

	public final void gravarLevantamento() throws TransmissaoException {
		GenericSOAP soap = new GenericSOAP();
		Vector vec = new Vector();
		Iterator it = MainController.getBensInventariados().iterator();
		while (it.hasNext()) {
			ItemLevantamento item = (ItemLevantamento) it.next();
			// Evitar erro no servidor
			if (item.getMarca() == null)
				item.setMarca("Não informada");
			vec.addElement(item.toString());
		}
		boolean sucess = Boolean.parseBoolean(soap.gravarLevantamento(
				MainController.getLevantamento(), vec, context));
		assertEquals(true, sucess);
	}

	public final void consultaLevantamento() throws SQLException,
			DatabaseException {
		Levantamento levantamento = (Levantamento) DatabaseHelper
				.getHelper(context).getLevantamentoDAO()
				.queryForId(MainController.getLevantamento().getId());
		// Verifica os dados do levantamento
		assertEquals(levantamento.getAno(), MainController.getLevantamento()
				.getAno());
		assertEquals(levantamento.getDescricao(), MainController
				.getLevantamento().getDescricao());
		assertEquals(levantamento.getNumero(), MainController.getLevantamento()
				.getNumero());
		assertEquals(levantamento.getStatus(), MainController.getLevantamento()
				.getStatus());
		assertEquals(levantamento.getDataCadastro(), MainController
				.getLevantamento().getDataCadastro());
		assertEquals(levantamento.getDataEstorno(), MainController
				.getLevantamento().getDataEstorno());
		assertEquals(levantamento.getLocal().getId(), MainController
				.getLocalidade().getId());
		assertEquals(levantamento.getTipo().getId(), MainController
				.getFinalidade().getId());
		assertEquals(levantamento.getUsuario().getId(), MainController
				.getUsuario().getId());

		// Verifica os dados dos itens do levantamento
		for (Persistencia obj : MainController.getBensInventariados()) {
			ItemLevantamento itemLocal = (ItemLevantamento) DatabaseHelper
					.getHelper(context).getItemDAO().queryForId(obj.getId());
			ItemLevantamento item = (ItemLevantamento) obj;
			assertEquals(item.getDenominacao(), itemLocal.getDenominacao());
			assertEquals(item.getEstado(), itemLocal.getEstado());
			assertEquals(item.getMarca(), itemLocal.getMarca());
			assertEquals(item.getNumTombamento(), itemLocal.getNumTombamento());
			assertEquals(item.getBem().getId(), itemLocal.getBem().getId());
			assertEquals(item.getLevantamento().getId(), itemLocal
					.getLevantamento().getId());
		}
	}
}
